package com.xj.opcua.data.Scheduled;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.xj.opcua.client.Client;
import com.xj.opcua.client.util.OpcUaClentUtils;
import com.xj.opcua.data.cache.OpcUaDataCache;
import com.xj.opcua.data.entity.OpcUaData;
import com.xj.opcua.data.entity.OpcUaSubscriptionData;
import com.xj.opcua.data.template.OpcUaDataTemplate;
import com.xj.opcua.data.template.OpcUaSubscriptionDataTemplate;
import com.xj.opcua.util.DateUtils;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class OpcUaClientTask {
	
	@Autowired
	private OpcUaSubscriptionDataTemplate opcUaSubscriptionDataTemplate;
	
	@Autowired
	private OpcUaDataTemplate opcUaDataTemplate;
	
	@Scheduled(fixedDelay=50)
	public void subscriptionData(){
		try {
			Date date = new Date(); 
			long time = date.getTime();
			for (Map.Entry<String,JSONObject> entry : OpcUaDataCache.subData.entrySet()) {
				JSONObject data = entry.getValue();
				OpcUaDataCache.subData.put(entry.getKey(), new JSONObject());
				if(data==null || data.size()==0) continue;
				String url = entry.getKey();
				OpcUaSubscriptionData before = opcUaSubscriptionDataTemplate.getByUrl(url);
				if(before!=null) {
					long interval = time - before.getTime();
					before.setInterval(interval);
					opcUaSubscriptionDataTemplate.updateSubscriptionData(before);
				}
			    OpcUaSubscriptionData opcUaSubscriptionData = new OpcUaSubscriptionData();
		    	opcUaSubscriptionData.setCreateTime(DateUtils.format(date, DateUtils.DATE_MS_PATTERN));
		    	opcUaSubscriptionData.setData(data);
		    	opcUaSubscriptionData.setUrl(url);
		    	opcUaSubscriptionData.setTime(time);
		    	opcUaSubscriptionDataTemplate.save(opcUaSubscriptionData);
			}
		}catch (Exception e) {
			log.error("subscriptionData:", e);
		}
	}
	
	@Scheduled(fixedDelay=50)
	public void opcData(){
		try {
			Date date = new Date(); 
			long time = date.getTime();
	        for (Map.Entry<String,List<NodeId>> entry:OpcUaDataCache.nodeIds.entrySet()){
	            String url = entry.getKey();
	            List<NodeId> list = entry.getValue();
	            OpcUaClient client = (OpcUaClient) Client.map.get(url).get(0);
	            if(client!=null) {
	            	Map<NodeId, Object> result = OpcUaClentUtils.readValues(client, list);
	            	JSONObject jsonData = new JSONObject();
	    			for (Map.Entry<NodeId, Object> resultEntry : result.entrySet()) {
	    				NodeId nodeId = resultEntry.getKey();
	    				Object value = resultEntry.getValue();
	    				String identifier = String.valueOf(nodeId.getIdentifier());
	    				jsonData.put("ns="+nodeId.getNamespaceIndex()+";"+identifier.replace(".", "#"), value);
	    			}
	    			if(jsonData!=null && jsonData.size()>0) {
	    				OpcUaData before = opcUaDataTemplate.getByUrl(url);
	    				if(before!=null) {
	    					long interval = time - before.getTime();
	    					before.setInterval(interval);
	    					opcUaDataTemplate.updateData(before);
	    				}
	    				OpcUaData opcUaData = new OpcUaData();
	    				opcUaData.setCreateTime(DateUtils.format(date, DateUtils.DATE_MS_PATTERN));
	    				opcUaData.setData(jsonData);
	    				opcUaData.setUrl(url);
	    				opcUaData.setTime(time);
	    				opcUaDataTemplate.save(opcUaData);
	    			}
	            }
	        }
		}catch (Exception e) {
			log.error("opcData:", e);
		}
	}

}
